home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ivl / src / hufilec.ars < prev    next >
Text File  |  2000-06-17  |  44KB  |  1,663 lines

  1. /*
  2. *    ファイル取り扱い関数群(for Human68k)
  3. *
  4. *    from Dec. 3,1993    by dummy.x.(with J-S.I.)
  5. *
  6. *    このソースは arr.x によってコンパイルされます。
  7. */
  8. -* -O -Wall
  9. -
  10. -    ここからしばらくアセンブラソース
  11. -
  12. -- Common Header
  13.     .include    doscall.mac
  14.     .include    iocscall.mac
  15.  
  16.     .nlist
  17.     .include    general.mac
  18.     .list
  19.  
  20. -_isponly.s
  21. * 定数定義
  22.         * __FILES バッファ構造
  23.     .offset    0
  24. __ATR:        .ds.b    1
  25. __DRVNO:    .ds.b    1
  26. __DIRCLS:    .ds.w    1
  27. __DIRFAT:    .ds.w    1
  28. __DIRSEC:    .ds.w    1
  29. __DIRPOS:    .ds.w    1
  30. __FILENAME:    .ds.b    8
  31. __EXT:        .ds.b    3
  32. _ATR:        .ds.b    1
  33. _TIME:        .ds.w    1
  34. _DATE:        .ds.w    1
  35. _FILELEN:    .ds.l    1
  36. _NAME:        .ds.b    18+1+3+1    *<base>+'.'+<ext>+'\0'
  37.         .even.
  38. _FBUF_LEN:
  39.  
  40. * スタックフレーム状況
  41. LOCALSIZE    equ    -(_FBUF_LEN)
  42.     .offset    LOCALSIZE
  43. _FBUF:    .ds.b    _FBUF_LEN    *__FILES バッファ
  44.     .ds.l    1        *フレームポインタ
  45.     .ds.l    1        *リターンアドレス
  46. _FNAMP:    .ds.l    1        *引数:    fnamp
  47.  
  48.     .text
  49.     .even
  50. *---------------------------------------------------------------
  51. *int is_path_only(const char *fnamp)
  52. * 指定されたファイル名が、実はパス名だけかどうか調べる
  53. *    引数:    fnamp    - 被検査ファイル名へのポインタ
  54. *    返値:    パス名だけだったら !0、ファイル名も含まれていたら 0
  55. *    注記    * おそらく、判断条件は今のままでは不完全である。
  56. *---------------------------------------------------------------
  57.     .xdef    _is_path_only
  58. _is_path_only:
  59.     link    a6,#LOCALSIZE
  60.     move.l    _FNAMP(a6),d1    *d1.l=fnamp
  61.             * 文字列の最後がパス区切り文字ならパス名
  62.     move.l    d1,a0        *a0=fnamp
  63. @@:    tst.b    (a0)+
  64.     bne.s    @b
  65.     move.b    -2(a0),d0    *d0.b=最後の一文字
  66.     cmp.b    #'\',d0
  67.     beq.s    ispo_only
  68.     cmp.b    #':',d0
  69.     beq.s    ispo_only
  70.     cmp.b    #'/',d0
  71.     beq.s    ispo_only
  72.             * 同名のディレクトリが既に存在していて、
  73.     move.w    #SUBDIR,-(sp)
  74.     move.l    d1,-(sp)
  75.     pea.l    _FBUF(a6)
  76.     DOS    __FILES
  77.     tst.l    d0
  78.     bmi.s    ispo_not
  79.             * しかもワイルドカードが使われていなければパス名
  80.     cmp.w    #$ffff,_FBUF+__DIRPOS(a6)
  81.     bne.s    ispo_not
  82.  
  83. ispo_only:        * パス名のみだッ!
  84.     moveq.l    #1,d0
  85.     unlk    a6
  86.     rts
  87.  
  88. ispo_not:        * ファイル名も含まれているッ!
  89.     moveq.l    #0,d0
  90.     unlk    a6
  91.     rts
  92. *---------------------------------------------------------------
  93.     .end
  94.  
  95. -_getxpos.s
  96.  
  97. * スタックフレーム状況
  98.     .offset    0
  99.     .ds.l    1        *リターンアドレス
  100. _FNAMP:    .ds.l    1        *引数:    fnamp
  101.  
  102.     .text
  103.     .even
  104. *---------------------------------------------------------------
  105. *char *getextpos(const char *fnamp)
  106. * 拡張子の存在位置を取得する
  107. *    引数:    fnamp    - 被検査ファイル名アドレス
  108. *    返値:    拡張子(らしきもの)があればその開始位置('.'の位置)
  109. *        なければ NULL
  110. *---------------------------------------------------------------
  111.     .xdef _getextpos
  112. _getextpos:
  113.     move.l    _FNAMP(sp),d2
  114.     moveq.l    #0,d0        *d0.l=拡張子がなかった時の返値(NULL)
  115.     move.l    d2,a0
  116. @@:    tst.b    (a0)+        *fnamp の最後へ移動する
  117.     bne.s    @b        *
  118.     subq.w    #1,a0        *行き過ぎたぶん引き戻す
  119.     bra.s    gxpos_loop    * ※getextpos0() 内のラベルに飛ぶ
  120.  
  121. *---------------------------------------------------------------
  122. *char *getextpos0(const char *fnamp)
  123. * 拡張子の存在位置を取得する(ない時は最後の '\0' アドレスを返す版)
  124. *    引数:    fnamp    - 被検査ファイル名アドレス
  125. *    返値:    拡張子(らしきもの)があればその開始位置('.'の位置)
  126. *        なければ fnamp の最後の '\0' のアドレス
  127. *    注記    * この関数で拡張子がなかったことを判断するには、
  128. *            「返したアドレスの文字が '\0' か」
  129. *        を調べればいい。
  130. *---------------------------------------------------------------
  131.     .xdef _getextpos0
  132. _getextpos0:
  133.     move.l    _FNAMP(sp),d2
  134.     move.l    d2,a0
  135. @@:    tst.b    (a0)+        *fnamp の最後へ移動する
  136.     bne.s    @b        *
  137.     subq.w    #1,a0        *行き過ぎたぶん引き戻す
  138.     move.l    a0,d0        *d0.l=拡張子がなかった時の返値('\0' の位置)
  139.  
  140.     *※ここから下は getextpos() と共用している。
  141.     * 変更は“どちらにも影響がないように”気を付けて
  142.     *行なうように。
  143.     *
  144.     *ここに来た時点でのレジスタの意味:
  145.     *    d0.l    - 拡張子が見つからなかった時の返値
  146.     *    d2.l    - fnamp
  147.     *    a0    - fnamp の最後 '\0' のアドレス
  148. gxpos_loop:
  149.     cmp.l    a0,d2        *ファイル名の先頭に
  150.     bhs.s    gxpos0        *達したら拡張子は指定されていない
  151.             * 文字判定
  152.     move.b    -(a0),d1    *d1.b=文字
  153.             * パス区切り文字判定
  154.     cmpi.b    #'\',d1        *パス区切り文字に
  155.     beq.s    gxpos0        *ぶつかっちゃったら
  156.     cmpi.b    #':',d1        *拡張子は
  157.     beq.s    gxpos0        *指定されていない
  158.     cmp.b    #'/',d1        *
  159.     beq.s    gxpos0        *
  160.             * 拡張子開始文字判定
  161.     cmp.b    #'.',d1        *'.'だったら
  162.     bne.s    gxpos_loop    *拡張子発見!
  163.  
  164. gxpos_findext:        * 拡張子発見
  165.     move.l    a0,d0        *そのアドレスを返値に
  166.  
  167. gxpos0:            * 共通脱出口
  168.     rts
  169. *---------------------------------------------------------------
  170.     .end
  171.  
  172. -_fcatext.s
  173.  
  174. * スタックフレーム状況
  175. ;;;REGLST    reg    
  176.     .offset    0
  177. ;;;    .ds.l    0        *退避レジスタ
  178.     .ds.l    1        *リターンアドレス
  179. _FNAMP:    .ds.l    1        *引数:    fnamp
  180. _EXTP:    .ds.l    1        *引数:    extp
  181.  
  182.     .text
  183.     .even
  184. *---------------------------------------------------------------
  185. *char *fcatext(char *fnamp, const char *extp)
  186. * ファイル名に拡張子を付加する
  187. *    拡張子がある場合は付加しない
  188. *
  189. *    引数:    fnamp    - ファイル名文字列アドレス
  190. *        extp    - 拡張子文字列アドレス
  191. *    返値:    fnamp の値
  192. *    注記    * extp の最初には '.'(ピリオド)があってもなくても構わない。
  193. *        * 付加する場合、fnamp の後ろには十分な余裕が必要である。
  194. *---------------------------------------------------------------
  195.     .xdef _fcatext
  196. _fcatext:
  197.     move.l    _FNAMP(sp),d0
  198.     move.l    _EXTP(sp),a1
  199.     move.l    d0,a0
  200. @@:    tst.b    (a0)+        *ファイル名末尾アドレスを取得
  201.     bne.s    @b        *
  202.     subq.w    #1,a0        *行き過ぎたぶんを引き戻し
  203.     movea.l    a0,a2        *そのアドレスを a2 にも持っておく
  204.  
  205. catx_findx:        * 拡張子位置の取得
  206.     cmp.l    a0,d0        *ファイル名の最初に達したら
  207.     bhs.s    catx_cat    *拡張子は指定されていない
  208.             * 文字判定
  209.     move.b    -(a0),d1    *d1.b=文字
  210.             * パス区切り文字判定
  211.     cmpi.b    #'\',d1        *パス区切り文字に
  212.     beq.s    catx_cat    *ぶつかっちゃったら
  213.     cmpi.b    #':',d1        *拡張子は
  214.     beq.s    catx_cat    *指定されていない
  215.     cmp.b    #'/',d1        *
  216.     beq.s    catx_cat    *
  217.             * 拡張子開始文字判定
  218.     cmp.b    #'.',d1        *'.'でなければ
  219.     bne.s    catx_findx    *次の文字を調べる
  220. catx0:
  221.     rts
  222.  
  223. catx_cat:        * 拡張子を付加する
  224.     moveq.l    #'.',d1
  225.     cmp.b    (a1),d1        *extp に '.' がなかったら
  226.     beq.s    @f        *
  227.     move.b    d1,(a2)+    *先に '.' を転送しておく
  228. @@:            * 拡張子を複写
  229.     move.b    (a1)+,(a2)+
  230.     bne.s    @b
  231.     rts
  232. *---------------------------------------------------------------
  233.     .end
  234.  
  235. -_fchgext.s
  236.  
  237. * スタックフレーム状況
  238. ;;;REGLST    reg    
  239.     .offset    0
  240. ;;;    .ds.l    0        *退避レジスタ
  241.     .ds.l    1        *リターンアドレス
  242. _FNAMP:    .ds.l    1        *引数:    fnamp
  243. _EXTP:    .ds.l    1        *引数:    extp
  244.  
  245.     .text
  246.     .even
  247. *---------------------------------------------------------------
  248. *char *fchgext(char *fnamp, const char *extp)
  249. * ファイル名の拡張子を付け替える
  250. *    拡張子がなければ付加する
  251. *
  252. *    引数:    fnamp    - ファイル名文字列アドレス
  253. *        extp    - 拡張子文字列アドレス
  254. *    返値:    fnamp の値
  255. *    注記    * extp の最初には '.'(ピリオド)があってもなくても構わない。
  256. *        * 付加する場合、fnamp の後ろには十分な余裕が必要である。
  257. *---------------------------------------------------------------
  258.     .xdef _fchgext
  259. _fchgext:
  260.     move.l    _FNAMP(sp),d0
  261.     move.l    _EXTP(sp),a1
  262.     move.l    d0,a0
  263. @@:    tst.b    (a0)+        *ファイル名末尾アドレスを取得
  264.     bne.s    @b        *
  265.     subq.w    #1,a0        *行き過ぎたぶんを引き戻し
  266.     movea.l    a0,a2        *そのアドレスを a2 にも持っておく
  267.  
  268. chgx_findx:        * 拡張子位置の取得
  269.     cmp.l    a0,d0        *ファイル名の最初に達したら
  270.     bhs.s    chgx_nofound    *拡張子は指定されていない
  271.             * 文字判定
  272.     move.b    -(a0),d1    *d1.b=文字
  273.             * 拡張子開始文字判定
  274.     cmp.b    #'.',d1        *'.'だったら
  275.     beq.s    chgx_found    *拡張子発見!
  276.             * パス区切り文字判定
  277.     cmpi.b    #'\',d1        *パス区切り文字に
  278.     beq.s    chgx_nofound    *ぶつかっちゃったら
  279.     cmpi.b    #':',d1        *拡張子は
  280.     beq.s    chgx_nofound    *指定されていない
  281.     cmp.b    #'/',d1        *
  282.     bne.s    chgx_findx    *
  283.  
  284. chgx_nofound:        * 拡張子がなかった
  285.     movea.l    a2,a0        *ファイル名の後に付加する
  286.  
  287. chgx_found:        *拡張子があった
  288.  
  289. chgx_chg:        *拡張子付替
  290.     moveq.l    #'.',d1
  291.     cmp.b    (a1),d1        *extp に '.' がなかったら
  292.     beq.s    @f        *
  293.     move.b    d1,(a0)+    *先に '.' を転送しておく
  294. @@:            * 拡張子を複写
  295.     move.b (a1)+,(a0)+
  296.     bne.s    @b
  297.  
  298. chgx0:
  299.     rts
  300. *---------------------------------------------------------------
  301.     .end
  302.  
  303. -_issamef.s
  304.  
  305. * 外部参照
  306.     .xref    _memcmp,_stricmp    * define in C libraly
  307.     .xref    _strnicmp        * define in dummyc.a
  308.  
  309. * 定数定義
  310.         * __FILES バッファ構造
  311.     .offset    0
  312. __ATR:        .ds.b    1
  313. __DRVNO:    .ds.b    1
  314. __DIRCLS:    .ds.w    1
  315. __DIRFAT:    .ds.w    1
  316. __DIRSEC:    .ds.w    1
  317. __DIRPOS:    .ds.w    1
  318. __FILENAME:    .ds.b    8
  319. __EXT:        .ds.b    3
  320. _ATR:        .ds.b    1
  321. _TIME:        .ds.w    1
  322. _DATE:        .ds.w    1
  323. _FILELEN:    .ds.l    1
  324. _NAME:        .ds.b    18+1+3+1    *<base>+'.'+<ext>+'\0'
  325.         .even.
  326. _FBUF_LEN:
  327. CMPSIZE_1    =    __FILENAME        *__ATR~__DIRPOS
  328. CMPSIZE_2    =    __EXT-__FILENAME    *__FILENAME
  329. CMPSIZE_3    =    _ATR-__EXT        *__EXT
  330. CMPSIZE_4    =    _NAME-_ATR        *_ATR~_FILELEN
  331. *CMPSIZE_5 は _NAME を文字列終わりまで比較
  332.  
  333. * スタックフレーム状況
  334. REGLST    reg    d3/a3/a4/a5
  335. LOCALSIZE    equ    -(_FBUF_LEN*2)
  336.     .offset    LOCALSIZE
  337. _FBUF1:    .ds.b    _FBUF_LEN    *fn1p 用 __FILES バッファ
  338. _FBUF2:    .ds.b    _FBUF_LEN    *fn2p 用 __FILES バッファ
  339.     .ds.l    1        *フレームポインタ
  340.     .ds.l    1        *リターンアドレス
  341. _FN1P:    .ds.l    1        *引数:    fn1p
  342. _FN2P:    .ds.l    1        *引数:    fn2p
  343.  
  344.     .text
  345.     .even
  346. *---------------------------------------------------------------
  347. *int is_same_file(const char *fn1p, const char *fn2p)
  348. * 二つのファイル名の指すファイルの実体が同じものかどうか調べる
  349. *    引数:    fn1p,fn2p    - 被比較ファイル名1,2
  350. *    返値:    二つが同じファイルなら !0、違っていたら 0
  351. *    注記    * 片方のファイルが見つからない場合は、「違っている」として
  352. *        0 を返す。
  353. *         また、両方とも見つからない場合は「同じ」として !0 を返す。
  354. *    警告    * 現在の比較方法は、
  355. *            「両方のファイルを _dos_files() にかけ、互いの
  356. *              _filbuf を公開/非公開部分を含めて全て比較する」
  357. *        というもので、決して完璧なものではない。
  358. *         また、lndrv や TwentyOne などの Human 拡張プログラムを
  359. *        使われた場合の動作は不明である(少なくとも、「ファイル名の
  360. *        大文字小文字を区別する」ようにした場合には確実に問題になる
  361. *        だろう)。
  362. *---------------------------------------------------------------
  363.     .xdef    _is_same_file
  364. _is_same_file:
  365.     link    a6,#LOCALSIZE
  366.     movem.l    REGLST,-(sp)
  367.     moveq.l    #0,d3        *d3=result
  368.             * fn1p を __FILES
  369.     lea.l    _FBUF1(a6),a3    *a3=fbuf1
  370.     move.w    #ARCHIVE,-(sp)
  371.     move.l    _FN1P(a6),-(sp)
  372.     pea.l    (a3)
  373.     DOS    __FILES
  374.     lea.l    10(sp),sp
  375.     tst.l    d0
  376.     smi.b    d1        *d1.b=err1
  377.             * fn2p を __FILES
  378.     lea.l    _FBUF2(a6),a4    *a4=fbuf2
  379.     move.w    #ARCHIVE,-(sp)
  380.     move.l    _FN2P(a6),-(sp)
  381.     pea.l    (a4)
  382.     DOS    __FILES
  383.     lea.l    10(sp),sp
  384.     tst.l    d0
  385.     smi.b    d0        *d0.b=err2
  386.             * __FILES の結果を見る
  387.     cmp.b    d1,d0        *どちらも結果が
  388.     bne.s    issamf0    *同じ値になってたら
  389.             * err1 によって状況判定
  390.     tst.b    d1        *err1 != 0 なら
  391.     bne.s    issamf_same    *どっちもなかった...同じということにする
  392.                 *どっちもあった...
  393.             * __FILES バッファの中身を比較
  394.     lea.l    _memcmp(OPC),a5
  395.     pea.l    CMPSIZE_1.w    * __ATR~__DIRPOS
  396.     pea.l    (a3)
  397.     pea.l    (a4)
  398.     jsr    (a5)
  399.     lea.l    12(sp),sp
  400.     tst.l    d0
  401.     bne.s    issamf0
  402.  
  403.     pea.l    CMPSIZE_4.w    * _ATR~_FILELEN
  404.     pea.l    _ATR(a3)
  405.     pea.l    _ATR(a4)
  406.     jbsr    (a5)
  407.     lea.l    12(sp),sp
  408.     tst.l    d0
  409.     bne.s    issamf0
  410.  
  411.     lea.l    _strnicmp(OPC),a5
  412.     pea.l    CMPSIZE_2.w    * __FILENAME
  413.     pea.l    __FILENAME(a3)
  414.     pea.l    __FILENAME(a4)
  415.     jbsr    (a5)
  416.     lea.l    12(sp),sp
  417.     tst.l    d0
  418.     bne.s    issamf0
  419.  
  420.     pea.l    CMPSIZE_3.w    * __EXT
  421.     pea.l    __EXT(a3)
  422.     pea.l    __EXT(a4)
  423.     jbsr    (a5)
  424.     lea.l    12(sp),sp
  425.     tst.l    d0
  426.     bne.s    issamf0
  427.  
  428.     pea.l    _NAME(a3)    * _NAME
  429.     pea.l    _NAME(a4)
  430.     jbsr    _stricmp
  431.     addq.w    #8,sp
  432.     tst.l    d0
  433.     bne.s    issamf0
  434.  
  435. issamf_same:        * 同じファイルだッ!
  436.     moveq.l    #1,d3
  437.  
  438. issamf0:
  439.     move.l    d3,d0
  440.     movem.l    (sp)+,REGLST
  441.     unlk    a6
  442.     rts
  443. *---------------------------------------------------------------
  444.     .end
  445.  
  446. -_cfpaseq.s
  447.  
  448. * 外部参照
  449.     .xref    _path_separator        * define in dummyc.a
  450.  
  451. * スタックフレーム状況
  452. REGLST    reg    a3-a5
  453.     .offset    0
  454.     .ds.l    3        *退避レジスタ
  455.     .ds.l    1        *リターンアドレス
  456. _DSTP:    .ds.l    1        *引数:    dstp
  457. _ENVPP:    .ds.l    1        *引数:    envpp
  458.  
  459.     .text
  460.     .even
  461. *---------------------------------------------------------------
  462. *char *cut_from_pathseq(char *dstp, const char **envpp)
  463. * 複数のパス名が並んでいる文字列の、最初のパス名を取り出す
  464. *    同じパラメータで複数回呼び出すことで、並んでいる順に次のパス名を
  465. *    取り出せる
  466. *
  467. *    引数:    dstp    - 複写先バッファアドレス
  468. *        envpp    - パス名列へのポインタへのポインタ
  469. *    返値:    通常は dstp の値、パス名列が終了していたら NULL
  470. *        (*dstp)        - 取り出したパス名(定義終了時には空文字列)
  471. *        (*envpp)    - 次のディレクトリ名の開始アドレス
  472. *    注記    * 「パス名列が終了していた」となるのは、最後のパス名を
  473. *        取り出した後に、更に取り出そうとした時である。
  474. *        * パス名は、環境変数 path の形式で並んでいるものとする。:
  475. *            <path1>;<path2>;..;<pathn>
  476. *---------------------------------------------------------------
  477.     .xdef    _cut_from_pathseq
  478. _cut_from_pathseq:
  479.     movem.l    REGLST,-(sp)
  480.     move.l    _DSTP(sp),a3    *a3=dstp
  481.     move.l    _ENVPP(sp),a4    *a4=envpp
  482.     movea.l    (a4),a5        *a5=*envp
  483.     tst.b    (a5)        * パス名列が終了してたら
  484.     beq.s    cpseq_ended    * その処理を
  485.  
  486. cpseq_cont:        * まだパス名がある
  487.             * パス名を '\0' か ';' まで切り出す
  488. @@:    move.b    (a5)+,d0
  489.     beq.s    cpseq_ct1
  490.     cmpi.b    #';',d0
  491.     beq.s    cpseq_ct1
  492.     move.b    d0,(a3)+
  493.     bra.s    @b
  494. cpseq_ct1:        * 「パス区切り文字」で終わっていなければ付加する
  495.     move.b    -1(a3),d0    *d0.b=最後の文字
  496.     cmpi.b    #'\',d0        *がパス区切り文字
  497.     beq.s    cpseq_ct2    *
  498.     cmpi.b    #':',d0        *
  499.     beq.s    cpseq_ct2    *
  500.     cmpi.b    #'/',d0        *
  501.     beq.s    cpseq_ct2    *でなければ
  502.     jbsr    _path_separator    *パス区切り文字を
  503.     move.b    d0,(a3)+    *書き加えて
  504. cpseq_ct2:
  505.     clr.b    (a3)        *取り出したパス名を完結させる
  506.             * パス名列が ';' で終わってたら飛ばしておく
  507.     tst.b    -1(a5)        *ループの都合で1文字進んでいる
  508.     bne.s    @f        *終わったのが '\0' だったなら
  509.     subq.w    #1,a5        *1文字戻す('\0' を指すように)
  510. @@:    move.l    a5,(a4)        *そのアドレスをバッファに収める
  511.             *返値を設定
  512.     move.l    _DSTP(sp),d0    *dstp を返す
  513. cpseq0:
  514.     movem.l    (sp)+,REGLST
  515.     rts
  516.  
  517. cpseq_ended:        * パス名列は終了している
  518.     clr.b    (a3)        *バッファは空文字列
  519.     moveq.l    #0,d0        *NULL を返す
  520.     bra.s    cpseq0
  521. *---------------------------------------------------------------
  522.     .end
  523.  
  524. -_apatsep.s
  525.  
  526. * 外部参照
  527.     .xref    _path_separator        * define in dummyc.a
  528.  
  529. * スタックフレーム状況
  530. REGLST    reg    d3/a3
  531.     .offset    0
  532.         .ds.l    1+1        *退避レジスタ
  533.         .ds.l    1        *リターンアドレス
  534. _DIRNAMP:    .ds.l    1        *引数:    dirnamp
  535.  
  536.     .text
  537.     .even
  538. *---------------------------------------------------------------
  539. *char *append_path_separator(char *dirnamp)
  540. * ディレクトリ名末尾にパス区切り文字がなければ付加する
  541. *    引数:    dirnamp    - 被処理ディレクトリ名
  542. *    返値:    dirnamp の値
  543. *    注記    * dirnamp には、最低 2.b の余白が必要である。
  544. *---------------------------------------------------------------
  545.     .xdef    _append_path_separator
  546. _append_path_separator:
  547.     movem.l    REGLST,-(sp)
  548.     move.l    _DIRNAMP(sp),d3    *d3.l=dirnamp
  549.     move.l    d3,a3        *a3=dirnamp
  550. @@:    tst.b    (a3)+        *文字列の最後まで
  551.     bne.s    @b        *進めてから
  552.     subq.l    #2,a3        *最後の文字まで戻る
  553.     move.b    (a3)+,d0    *d0.b=最後の文字
  554.     cmp.b    #'\',d0        *がパス区切り文字
  555.     beq.s    apps0        *
  556.     cmp.b    #':',d0        *
  557.     beq.s    apps0        *
  558.     cmp.b    #'/',d0        *
  559.     beq.s    apps0        *でなかったら
  560.     jbsr    _path_separator    *パス区切り文字を
  561.     move.b    d0,(a3)+    *書き加えて
  562.     clr.b    (a3)        *文字列を完結させる
  563.  
  564. apps0:
  565.     move.l    d3,d0        *dirnamp を返す
  566.     movem.l    (sp)+,REGLST
  567.     rts
  568. *---------------------------------------------------------------
  569.     .end
  570.  
  571. -_gevpath.s
  572.  
  573. * 外部参照
  574.     .xref    _getenv        * define in C library.
  575.     .xref    _path_separator    * define in dummyc.a
  576.  
  577. * スタックフレーム状況
  578. REGLST        reg    a3
  579.     .offset    0
  580.         .ds.l    1        *退避レジスタ
  581.         .ds.l    1        *リターンアドレス
  582. _BUFP:        .ds.l    1        *引数:    bufp
  583. _ENVNAMP:    .ds.l    1        *引数:    envnamp
  584.  
  585.     .text
  586.     .even
  587. *---------------------------------------------------------------
  588. *char *get_env_path(char *bufp, const char *envnamp)
  589. * 環境変数に定義されたパス名の取得
  590. *    引数:    bufp    - 取得パス名格納バッファアドレス
  591. *        envnamp    - 環境変数名文字列アドレス
  592. *    返値:    bufp の値
  593. *    注記    * 取得したパス名の最後に '\' か ':' か '/' がない場合、
  594. *            環境変数 SLASH が定義されていれば '/'
  595. *                     されていなければ '\'
  596. *        を書き加える。
  597. *        * 指定の環境変数が定義されていなかったら bufp は
  598. *        一切書き換えない。
  599. *---------------------------------------------------------------
  600.     .xdef    _get_env_path
  601. _get_env_path:
  602.     move.l    REGLST,-(sp)
  603.     move.l    _BUFP(sp),a3
  604.             * 環境変数取得
  605.     move.l    _ENVNAMP(sp),-(sp)
  606.     jbsr    _getenv
  607.     addq.w    #4,sp
  608.     move.l    d0,a0        * 環境変数が定義されてなければ
  609.     beq.s    gevpat0        * 何もしないで返る
  610.             * 定義内容をバッファに複写
  611. @@:    move.b (a0)+,(a3)+
  612.     bne.s    @b        * a0,a3 は共に1文字ぶん行きすぎてるので注意
  613.             * 「パス区切り文字」で終わっていなければ付加する
  614.     subq.l    #2,a3        *最後の文字まで引き戻す
  615.     move.b    (a3)+,d0    *d0.b=最後の文字
  616.     cmpi.b    #'\',d0        *がパス区切り文字
  617.     beq.s    gevpat0        *
  618.     cmpi.b    #':',d0        *
  619.     beq.s    gevpat0        *
  620.     cmpi.b    #'/',d0        *
  621.     beq.s    gevpat0        *でなかったら
  622.     jbsr    _path_separator    *パス区切り文字を
  623.     move.b    d0,(a3)+    *末尾追加して
  624.     clr.b    (a3)        *文字列を完結
  625.  
  626. gevpat0:        * 共通脱出口
  627.     move.l    _BUFP(sp),d0    *bufp を返す
  628.     move.l    (sp)+,REGLST
  629.     rts
  630. *---------------------------------------------------------------
  631.     .end
  632.  
  633. -_pathsep.s
  634.  
  635. * 外部参照
  636.     .xref    _getenv        * define in C library.
  637.     .xref    __path_separator_envname    *define in dummyc.a
  638.  
  639.     .text
  640.     .even
  641. *---------------------------------------------------------------
  642. *char path_separator(void)
  643. * ディレクトリの区切り文字を取得する
  644. *    返値:    環境変数 SLASH が定義されていれば '/'
  645. *                 されていなければ '\'
  646. *---------------------------------------------------------------
  647. REGLST    reg    d3/a3
  648.     .xdef    _path_separator
  649. _path_separator:
  650.     movem.l    REGLST,-(sp)
  651.     moveq.l    #0,d3
  652.     lea.l    _?sep_0(OPC),a3    *a3=取得済み文字格納バッファ
  653.     move.b    (a3),d3        *既に取得済みなら
  654.     bne.s    patsep0        *余計な処理をせずに済ませる
  655.  
  656.             * 環境変数が定義されているかどうかで文字を決める
  657.     pea.l    __path_separator_envname(OPC)    *環境変数名
  658.     jbsr    _getenv
  659.     addq.w    #4,sp
  660.     tst.l    d0        *環境変数が定義されてるかで
  661.     bne.s    patsep_define    *文字を変える
  662. patsep_undef:        * 定義されていない
  663.     move.b    #'\',d3
  664.     bra.s    patsep_stock
  665. patsep_define:        * 定義されている
  666.     move.b    #'/',d3
  667. patsep_stock:
  668.     move.b    d3,(a3)
  669.  
  670. patsep0:
  671.     move.l    d3,d0
  672.     movem.l    (sp)+,REGLST
  673.     rts
  674.  
  675. *---------------------------------------------------------------
  676.     .bss
  677.  
  678. _?sep_0:        ;取得済みパス区切り文字
  679.     .ds.b    1
  680. *---------------------------------------------------------------
  681.     .end
  682.  
  683. -_isthpath.s
  684.     .text
  685.  
  686. * 外部参照
  687.     .xref    _strpbrk    * define in C library.
  688.  
  689. * スタックフレーム状況
  690.     .offset    0
  691.     .ds.l    1    *リターンアドレス
  692. _FNAMP:    .ds.l    1    *引数:    fnamp
  693.  
  694.     .text
  695.     .even
  696. *---------------------------------------------------------------
  697. *int is_there_path(const char *fnamp)
  698. * ファイル名にパス名が指定されているか調べる
  699. *    引数:    fnamp    - 被検査ファイル名へのポインタ
  700. *    返値:    パス名が指定されていれば !0、されていなければ 0
  701. *    注記    * パス名が指定されているかは、「ファイル名に
  702. *        '\' か '/' か ':' があるかどうか」で調べている。
  703. *---------------------------------------------------------------
  704.     .xdef    _is_there_path
  705. _is_there_path:
  706.     move.l    _FNAMP(sp),d0
  707.     pea.l    ?C0(OPC)
  708.     move.l    d0,-(sp)
  709.     jbsr    _strpbrk
  710.     addq.w    #8,sp
  711.     tst.l    d0
  712.     sne.b    d1
  713.     moveq.l    #1,d0
  714.     move.b    d1,d0    *d0.l=ff(!0):パス名指定あり/=0:指定なし
  715.     rts
  716. *---------------------------------------------------------------
  717.     .text
  718. ?C0:        * パス区切り文字群
  719.     .dc.b '\/:',0
  720. *---------------------------------------------------------------
  721.     .end
  722.  
  723. -_getfsiz.s
  724.  
  725. * 定数定義
  726. _FLS_FILELEN    equ    26        *__FILES バッファ:ファイルサイズ
  727.  
  728. * スタックフレーム状況
  729. LOCALSIZE    equ    -54
  730.     .offset    LOCALSIZE
  731. _FILESBUF:    .ds.b    54        *__FILES バッファ
  732.         .ds.l    1        *フレームポインタ
  733.         .ds.l    1        *リターンアドレス
  734. _FNAMP:        .ds.l    1        *引数:    fnamp
  735.  
  736.     .text
  737.     .even
  738. *---------------------------------------------------------------
  739. *long get_file_size(const char *fnamp)
  740. * 指定ファイルのファイルサイズを取得する
  741. *    引数:    fnamp    - ファイル名文字列へのポインタ
  742. *    返値:    ファイルサイズ(>=0)、ファイルがなかったら <0
  743. *    注記    * ファイルがとんでもなく大きい(2Gを超えるような)場合、
  744. *        エラーとして扱われてしまう(負値になってしまうため)。
  745. *---------------------------------------------------------------
  746.     .xdef    _get_file_size
  747. _get_file_size:
  748.     link    a6,#LOCALSIZE
  749.     move.w    #$2f,-(sp)
  750.     move.l    _FNAMP(a6),-(sp)
  751.     pea.l    _FILESBUF(a6)
  752.     DOS    __FILES
  753.     tst.l    d0
  754.     bmi.s    gfsz0
  755.     move.l    _FILESBUF+_FLS_FILELEN(a6),d0
  756. gfsz0:
  757.     unlk    a6
  758.     rts
  759. *---------------------------------------------------------------
  760.     .end
  761.  
  762. -_ispasep.s
  763.  
  764. * スタックフレーム状況
  765.     .offset    0
  766.     .ds.l    1    *リターンアドレス
  767. _CH:    .ds.l    1    *引数:    ch
  768.  
  769.     .text
  770.     .even
  771. *---------------------------------------------------------------
  772. *int is_path_separator(int ch)
  773. * 文字がパス名の区切り文字かを調べる
  774. *    引数:    ch    - 被検査文字
  775. *    返値:    区切り文字('\', '/', ':')なら !0、違うならば 0
  776. *    注記    * これで言う「区切り文字」とは '\'(バックスラッシュ),
  777. *        '/'(スラッシュ), ':'(セミコロン) のどれかである。
  778. *---------------------------------------------------------------
  779.     .xdef    _is_path_separator
  780. _is_path_separator:
  781.     move.b    _CH+3(sp),d1
  782.     moveq.l    #0,d0
  783.     cmpi.b    #'\',d1
  784.     beq.s    ips_not
  785.     cmpi.b    #':',d1
  786.     beq.s    ips_not
  787.     cmpi.b    #'/',d1
  788.     bne.s    ips0
  789. ips_not:
  790.     moveq.l    #1,d0
  791. ips0:
  792.     rts
  793. *---------------------------------------------------------------
  794.     .end
  795.  
  796. -_gdrvfre.s
  797.  
  798. * スタックフレーム状況
  799. LOCALSIZE    equ    -8
  800.     .offset    LOCALSIZE
  801. _FREBUF:    .ds.b    8        *__DSKFRE バッファ
  802.         .ds.l    1        *フレームポインタ
  803.         .ds.l    1        *リターンアドレス
  804. _DRVNO:        .ds.l    1        *引数:    drvno
  805.  
  806.     .text
  807.     .even
  808. *---------------------------------------------------------------
  809. *long get_drive_free(int drvno)
  810. * 指定ドライブ番号の空き容量を得る
  811. *    引数:    drvno    - ドライブ番号(=0:カレント/=1-26:A-Z)
  812. *    返値:    空き容量(byte単位)
  813. *        値が負数の場合はエラー
  814. *---------------------------------------------------------------
  815.     .xdef    _get_drive_free
  816. _get_drive_free:
  817.     link    a6,#LOCALSIZE
  818.     pea    _FREBUF(a6)
  819.     move.w 10(a6),-(sp)
  820.     DOS    __DSKFRE
  821.     unlk    a6
  822.     rts
  823. *---------------------------------------------------------------
  824.     .end
  825.  
  826. -_gdrvno.s
  827.  
  828. * スタックフレーム状況
  829.     .offset    0
  830.         .ds.l    1        *リターンアドレス
  831. _DRVNAMP:    .ds.l    1        *引数:    drvnamp
  832.  
  833.     .text
  834.     .even
  835. *---------------------------------------------------------------
  836. *int get_drive_no(const char *drvnamp)
  837. * ドライブ名からドライブ番号を得る
  838. *    引数:    drvnamp    -ドライブ名("A:", "X:")
  839. *             (NULLまたは空文字列の場合はカレントドライブを取得する)
  840. *    返値:    ドライブ番号(=0:引数異常/=1-26:A-Z)
  841. *---------------------------------------------------------------
  842.     .xdef    _get_drive_no
  843. _get_drive_no:
  844.     move.l    _DRVNAMP(sp),d0    *drvnamp が
  845.     beq.s    gdn_cur        *NULL か
  846.     move.l    d0,a0        *
  847.     tst.b    (a0)        *空文字列だったら
  848.     bne.s    gdn_moji    *
  849. gdn_cur:        * カレントドライブを得る
  850.     DOS    __CURDRV    *A=0,B=1,...
  851.     addq.l    #1,d0        *0~25→1~26
  852.     jbra    gdn0
  853. gdn_moji:        * ドライブ名から算出
  854.     moveq.l    #0,d0
  855.     move.b    (a0)+,d0
  856.     cmpi.b    #'A',d0        *英大文字の範囲を
  857.     blo.s    gdn_err        *下回ってたら文句なくエラー
  858.     cmpi.b    #'Z',d0        *範囲内
  859.     bhi.s    @f        *だったら
  860.     addi.b    #'a'-'A',d0    *小文字にする
  861. @@:    subi.b    #'a'-1,d0    *英小文字→数値変換
  862.     tst.b    d0        *1~
  863.     ble.s    gdn_err        *26 の範囲に
  864.     cmpi.b    #26,d0        *収まっていて
  865.     bgt.s    gdn_err        *
  866.     cmpi.b    #':',(a0)    *且つ2文字目が ':' なら
  867.     bne.s    gdn_err        *正しいドライブ名なのでその値を返す
  868. gdn0:
  869.     rts
  870.  
  871. gdn_err:        * ドライブ名がおかしい
  872.     moveq.l #0,d0
  873.     rts
  874. *---------------------------------------------------------------
  875.     .end
  876.  
  877. -_ishunam.s
  878.  
  879. * スタックフレーム状況
  880. LOCALSIZE    equ    -92
  881.     .offset    LOCALSIZE
  882. _NAMECKBUF:    .ds.b    92        *__NAMECK バッファ
  883.         .ds.l    1        *フレームポインタ
  884.         .ds.l    1        *リターンアドレス
  885. _FNAMP:        .ds.l    1        *引数:    fnamp
  886.  
  887.     .text
  888.     .even
  889. *---------------------------------------------------------------
  890. *int is_human_name(const char *fnamp)
  891. * ファイル名として正しいか判定する
  892. *    引数:    fnamp    - 被検査ファイル名文字列アドレス
  893. *    返値    正しければ !0、異常なら 0
  894. *---------------------------------------------------------------
  895.     .xdef    _is_human_name
  896. _is_human_name:
  897.     link    a6,#LOCALSIZE
  898.     pea.l    _NAMECKBUF(a6)
  899.     move.l    _FNAMP(a6),-(sp)
  900.     DOS    __NAMECK
  901.     tst.l    d0
  902.     sge.b    d1
  903.     moveq.l    #0,d0        *d0.l=     0:異常
  904.     move.b    d1,d0        *    ff:正常
  905.     unlk    a6
  906.     rts
  907. *---------------------------------------------------------------
  908.     .end
  909.  
  910. -_fexist.s
  911.  
  912. * スタックフレーム状況
  913. LOCALSIZE    equ    -54
  914.     .offset    LOCALSIZE
  915. _FILESBUF:    .ds.b    54        *__FILES バッファ
  916.         .ds.l    1        *フレームポインタ
  917.         .ds.l    1        *リターンアドレス
  918. _FNAMP:        .ds.l    1        *引数:    fnamp
  919. _ATR:        .ds.l    1        *引数:    atr
  920.  
  921.     .text
  922.     .even
  923. *---------------------------------------------------------------
  924. *int fexist(const char *fnamp, int atr)
  925. * ファイルを探す
  926. *    引数:    fnamp    - 探索ファイル名
  927. *        atr    - 探索ファイルの属性
  928. *    返値:    あれば !0、なければ 0
  929. *---------------------------------------------------------------
  930.     .xdef    _fexist
  931. _fexist:
  932.     link    a6,#LOCALSIZE
  933.     move.w    _ATR+2(a6),-(sp)
  934.     move.l    _FNAMP(a6),-(sp)
  935.     pea.l    _FILESBUF(a6)
  936.     DOS    __FILES
  937.     tst.l    d0
  938.     sge.b    d1
  939.     moveq.l    #0,d0
  940.     move.b    d1,d0    * d0.l=ff(!0):ある/=0:ない
  941.     unlk    a6
  942.     rts
  943. *---------------------------------------------------------------
  944.     .end
  945.  
  946. -_gprognm.s
  947.  
  948. * 定数定義
  949. NCK_NAME    equ    67    *__NAMECK バッファ:ファイル主名の位置
  950.  
  951. * スタックフレーム状況
  952. LOCALSIZE    equ    -92
  953.     .offset    LOCALSIZE
  954. _NAMECKBUF:    .ds.b    92        *__NAMECK バッファ
  955.         .ds.l    1        *フレームポインタ
  956.         .ds.l    1        *リターンアドレス
  957. _BUFP:        .ds.l    1        *引数:    bufp
  958. _PNAMP:        .ds.l    1        *引数:    pnamp
  959.  
  960.     .text
  961.     .even
  962. *---------------------------------------------------------------
  963. *void get_prog_name(char *bufp, const char *pnamp)
  964. * プログラムタイトル抜き出し
  965. *    引数:    bufp    - プログラムタイトル格納バッファアドレス
  966. *        pnamp    - プログラム名へのポインタ(起動時の argv[0])
  967. *---------------------------------------------------------------
  968.     .xdef    _get_prog_name
  969. _get_prog_name:
  970.     link    a6,#LOCALSIZE
  971.             * プログラム名を構成要素に分解
  972.     lea.l    _NAMECKBUF(a6),a0
  973.     pea.l    (a0)
  974.     move.l    _PNAMP(a6),-(sp)
  975.     DOS    __NAMECK
  976. ;;;    ADDQA    12,sp
  977.             * プログラム名の「ファイル主名」をバッファに転送
  978.     ADDQA    NCK_NAME,a0
  979.     move.l    _BUFP(a6),a1
  980. @@:    move.b    (a0)+,(a1)+
  981.     bne.s    @b
  982. gpn0:
  983.     unlk    a6
  984.     rts
  985. *---------------------------------------------------------------
  986.     .end
  987.  
  988. -
  989. -    ここからしばらくCソース
  990. -
  991. -- Common Header
  992. #define    __DOS_INLINE__
  993. #include    <stdio.h>
  994. #include    <stdlib.h>
  995. #include    <ctype.h>
  996. #include    <string.h>
  997. #include    <jctype.h>
  998. #include    <jstring.h>
  999. #include    <sys\dos.h>
  1000. #include    "easymac.h"
  1001. #include    "dummyc.h"
  1002. #include    "hufilec.h"
  1003.  
  1004. /* データ構造定義 */
  1005. typedef struct _filbuf _filesbuf_t;    /* DOS __FILES ファイル情報 */
  1006. typedef struct _nameckbuf _nameckbuf_t;    /* DOS __NAMECK ファイル名解析情報 */
  1007.  
  1008. /* 大安易マクロ */
  1009. #define    is_path_sepa_mac(ch)    (((ch) == '\\') || ((ch) == ':') || ((ch) == '/'))
  1010.  
  1011.  
  1012. /*
  1013. *    ↓↓↓ ライブラリ共通関数 ↓↓↓
  1014. *        inline 展開されることを期待する
  1015. */
  1016. /* 自家製 strcpy()
  1017. *    引数:    dstp    - コピー先アドレス
  1018. *        srcp    - コピー元アドレス
  1019. */
  1020. static
  1021. void ___vstrcpy(char *dstp, const char *srcp)
  1022. {
  1023.     while (*dstp++ = *srcp++) {
  1024.     }
  1025. }
  1026.  
  1027.  
  1028. -_fcatxup.c
  1029. /* ファイル名に拡張子を付加する
  1030. *    元から拡張子があれば何もしない
  1031. *    ファイル名に英半角大文字が使われていれば拡張子を大文字変換し、
  1032. *    一文字も使われていなければ小文字変換して付加する
  1033. *    ex)    ファイル名:"Foo" 拡張子:"Bar" → "Foo.BAR"
  1034. *        ファイル名:"foo" 拡張子:"Bar" → "foo.bar"
  1035. *
  1036. *    引数:    fnamp    - ファイル名文字列アドレス
  1037. *        extp    - 拡張子文字列アドレス
  1038. *    返値:    fnamp の値
  1039. */
  1040. char *fcatext_upper(char *fnamp, const char *extp)
  1041. {
  1042.     char *xp;
  1043.  
  1044.     xp = getextpos0(fnamp);    /* 拡張子の位置取得 */
  1045.  
  1046.     if (*xp == '\0') {    /* 拡張子がなければ付加する */
  1047.         _nameckbuf_t nbuf;
  1048.  
  1049.         /* 拡張子付加 */
  1050.         if (*extp != '.') {    /* extp に '.' がなければ */
  1051.             *xp++ = '.';    /* 先に書き込んでおく */
  1052.         }
  1053.         ___vstrcpy(xp, extp);
  1054.  
  1055.         /* 拡張子の大小変更 */
  1056.         _dos_nameck(fnamp, &nbuf);    /* ファイル名を分解 */
  1057.         if (jstrchr_upper(nbuf.name)) {    /* ファイル名に大文字があれば */
  1058.             jstrupr(xp);        /* 全て大文字 */
  1059.         } else {            /* ファイル名が全て小文字なら */
  1060.             jstrlwr(xp);        /* 全て小文字 */
  1061.         }
  1062.     }
  1063.  
  1064.     return fnamp;
  1065. }
  1066.  
  1067. -_fcatxlo.c
  1068. /* ファイル名に拡張子を付加する
  1069. *    元から拡張子があれば何もしない
  1070. *    ファイル名に英半角小文字が使われていれば拡張子を小文字変換し、
  1071. *    一文字も使われていなければ大文字変換して付加する
  1072. *    ex)    ファイル名:"Foo" 拡張子:"Bar" → "Foo.bar"
  1073. *        ファイル名:"FOO" 拡張子:"Bar" → "FOO.BAR"
  1074. *
  1075. *    引数:    fnamp    - ファイル名文字列アドレス
  1076. *        extp    - 拡張子文字列アドレス
  1077. *    返値:    fnamp の値
  1078. */
  1079. char *fcatext_lower(char *fnamp, const char *extp)
  1080. {
  1081.     char *xp;
  1082.  
  1083.     xp = getextpos0(fnamp);    /* 拡張子の位置取得 */
  1084.  
  1085.     if (*xp == '\0') {    /* 拡張子がなければ付加する */
  1086.         _nameckbuf_t nbuf;
  1087.  
  1088.         /* 拡張子付加 */
  1089.         if (*extp != '.') {    /* extp に '.' がなければ */
  1090.             *xp++ = '.';    /* 先に書き込んでおく */
  1091.         }
  1092.         ___vstrcpy(xp, extp);
  1093.  
  1094.         /* 拡張子の大小変更 */
  1095.         _dos_nameck(fnamp, &nbuf);    /* ファイル名を分解 */
  1096.         if (jstrchr_lower(nbuf.name)) {    /* ファイル名に小文字があれば */
  1097.             jstrlwr(xp);        /* 全て小文字 */
  1098.         } else {            /* ファイル名が全て大文字なら */
  1099.             jstrupr(xp);        /* 全て大文字 */
  1100.         }
  1101.     }
  1102.  
  1103.     return fnamp;
  1104. }
  1105.  
  1106. -_fchgxup.c
  1107. /* ファイル名の拡張子を付け替える
  1108. *    拡張子がなければ付加する
  1109. *    ファイル名に英半角大文字が使われていれば拡張子を大文字変換し、
  1110. *    一文字も使われていなければ小文字変換して付け替える
  1111. *    ex)    ファイル名:"Foo.Baz" 拡張子:"Bar" → "Foo.BAR"
  1112. *        ファイル名:"foo.Baz" 拡張子:"Bar" → "foo.bar"
  1113. *
  1114. *    引数:    fnamp    - ファイル名文字列アドレス
  1115. *        extp    - 拡張子文字列アドレス
  1116. *    返値:    fnamp の値
  1117. */
  1118. char *fchgext_upper(char *fnamp, const char *extp)
  1119. {
  1120.     char *xp;
  1121.     _nameckbuf_t nbuf;
  1122.  
  1123.     /* 拡張子位置を探索 */
  1124.     xp = getextpos0(fnamp);
  1125.     if (*extp != '.') {    /* extp に '.' がなければ */
  1126.         *xp++ = '.';    /* 先に書き込んでおく */
  1127.     }
  1128.     ___vstrcpy(xp, extp);    /* そこに書き込む */
  1129.  
  1130.     /* 拡張子の大小変更 */
  1131.     _dos_nameck(fnamp, &nbuf);    /* ファイル名を分解 */
  1132.     if (jstrchr_upper(nbuf.name)) {    /* ファイル名に大文字があれば */
  1133.         jstrupr(xp);        /* 全て大文字 */
  1134.     } else {            /* ファイル名が全て小文字なら */
  1135.         jstrlwr(xp);        /* 全て小文字 */
  1136.     }
  1137.  
  1138.     return fnamp;
  1139. }
  1140.  
  1141. -_fchgxlo.c
  1142. /* ファイル名の拡張子を付け替える
  1143. *    拡張子がなければ付加する
  1144. *    ファイル名に英半角小文字が使われていれば拡張子を小文字変換し、
  1145. *    一文字も使われていなければ大文字変換して付け替える
  1146. *    ex)    ファイル名:"Foo.Baz" 拡張子:"Bar" → "Foo.bar"
  1147. *        ファイル名:"FOO.Baz" 拡張子:"Bar" → "FOO.BAR"
  1148. *
  1149. *    引数:    fnamp    - ファイル名文字列アドレス
  1150. *        extp    - 拡張子文字列アドレス
  1151. *    返値:    fnamp の値
  1152. */
  1153. char *fchgext_lower(char *fnamp, const char *extp)
  1154. {
  1155.     char *xp;
  1156.     _nameckbuf_t nbuf;
  1157.  
  1158.     /* 拡張子位置を探索 */
  1159.     xp = getextpos0(fnamp);
  1160.     if (*extp != '.') {    /* extp に '.' がなければ */
  1161.         *xp++ = '.';    /* 先に書き込んでおく */
  1162.     }
  1163.     ___vstrcpy(xp, extp);    /* そこに書き込む */
  1164.  
  1165.     /* 拡張子の大小変更 */
  1166.     _dos_nameck(fnamp, &nbuf);    /* ファイル名を分解 */
  1167.     if (jstrchr_lower(nbuf.name)) {    /* ファイル名に小文字があれば */
  1168.         jstrlwr(xp);        /* 全て小文字 */
  1169.     } else {            /* ファイル名が全て大文字なら */
  1170.         jstrupr(xp);        /* 全て大文字 */
  1171.     }
  1172.  
  1173.     return fnamp;
  1174. }
  1175.  
  1176. -_rdfall.c
  1177. /* 指定ファイルを全て読み込む
  1178. *    引数:    fnamp    - ファイル名文字列へのポインタ
  1179. *        fsizp    - ファイルサイズ格納変数へのポインタ(=NULL:書き込まない)
  1180. *    返値:    読み込めればその読み込んだメモリのアドレス
  1181. *        読み込みに失敗した場合は NULL
  1182. *        (*fsizp    - ファイルサイズ)
  1183. *    注記    * 読み込んだメモリは malloc() によって確保された
  1184. *        ものである。このため、その内容が不要になった時点で
  1185. *        メモリ解放をしなくてはならない。
  1186. *        * この関数が失敗するのは次の場合である。:
  1187. *            ・ファイルが存在しない
  1188. *            ・メモリが確保できない
  1189. *            ・ファイルの読み込みに失敗
  1190. *         このうち、最初の「ファイルが存在しない」時は (*fsizp) に
  1191. *        0 が格納される。また、他の理由で失敗した時は (*fsizp) に
  1192. *        ファイルサイズが格納される。
  1193. *        * 読み込みはバイナリで行なわれる。テキストデータを扱う
  1194. *        場合は注意すること。
  1195. */
  1196. void *read_file_all(const char *fnamp, unsigned long *fsizp)
  1197. {
  1198.     void *result = NULL;
  1199.     unsigned long fsiz = 0;
  1200.     FILE *fp;
  1201.     _filesbuf_t fbuf;
  1202.  
  1203.     if (_dos_files(&fbuf, fnamp, 0x2f) >= 0) {    /* どうやらファイルはあるらしい */
  1204.         fsiz = fbuf.filelen;    /* ファイルサイズ取得 */
  1205.         result = malloc(fsiz);    /* そのぶんだけメモリ確保 */
  1206.         if (result != NULL) {    /* 確保できれば */
  1207.             char errf = !0;    
  1208.             /* ファイルから読み込む */
  1209.             fp = fopen(fnamp, "rb");    /* まず開く */
  1210.             if (fp != NULL) {        /* 開けていれば読む */
  1211.                 if (fread(result, 1, fsiz, fp) == fsiz) {    /* 読み込めた */
  1212.                     errf = 0;    /* 読み込み失敗フラグクリア */
  1213.                 }
  1214.                 fclose(fp);
  1215.             }
  1216.             if (errf) {
  1217.                 free_mem(result);
  1218.             }
  1219.         }
  1220.     }
  1221.  
  1222.     /* 返値設定 */
  1223.     if (fsizp != NULL) {    /* ファイルサイズが必要なら */
  1224.         *fsizp = fsiz;    /* 書き込んでおく */
  1225.     }
  1226.     return result;
  1227. }
  1228.  
  1229. -_mfpath.c
  1230. /* ファイル名をフルパス展開、再構成する
  1231. *    引数:    fullp    - フルパス再構成先バッファアドレス
  1232. *        fnamp    - 展開したいファイル名文字列
  1233. *    返値:    正常終了時は 0
  1234. *        展開/構成に失敗したら <0 (Humanエラーコード)
  1235. *    注記    * fnamp と fullp の指す領域が重なっていても構わない。
  1236. *        * この関数ではファイルが実際にあるかどうかは確認しない。
  1237. */
  1238. int make_full_path(char *fullp, const char *fnamp)
  1239. {
  1240.     int result;
  1241.     _nameckbuf_t nbuf;
  1242.  
  1243.     result = _dos_nameck(fnamp, &nbuf);
  1244.     if (result != 0) {
  1245.         sprintf(fullp, "%c%c%s%s%s", nbuf.drive[0], nbuf.drive[1],
  1246.                 nbuf.path, nbuf.name, nbuf.ext);
  1247.         result = 0;
  1248.     }
  1249.     return result;
  1250. }
  1251.  
  1252. -- Common Header.
  1253. /*
  1254. *    ここから下はDOSコールを使わない関数を入れておく
  1255. */
  1256. #include    <stdio.h>
  1257. #include    <stdlib.h>
  1258. #include    <ctype.h>
  1259. #include    <string.h>
  1260. #include    <jctype.h>
  1261. #include    <jstring.h>
  1262. #include    "easymac.h"
  1263. #include    "dummyc.h"
  1264. #include    "hufilec.h"
  1265.  
  1266. /* データ構造定義 */
  1267. typedef struct _filbuf _filesbuf_t;    /* DOS __FILES ファイル情報 */
  1268. typedef struct _nameckbuf _nameckbuf_t;    /* DOS __NAMECK ファイル名解析情報 */
  1269.  
  1270. /* 大安易マクロ */
  1271. #define    is_path_sepa_mac(ch)    (((ch) == '\\') || ((ch) == ':') || ((ch) == '/'))
  1272.  
  1273.  
  1274. /*
  1275. *    ↓↓↓ ライブラリ共通関数 ↓↓↓
  1276. *        inline 展開されることを期待する
  1277. */
  1278. /* 自家製 strcpy()
  1279. *    引数:    dstp    - コピー先アドレス
  1280. *        srcp    - コピー元アドレス
  1281. */
  1282. static
  1283. void ___vstrcpy(char *dstp, const char *srcp)
  1284. {
  1285.     while (*dstp++ = *srcp++) {
  1286.     }
  1287. }
  1288.  
  1289. /* 自家製 stpcpy()
  1290. *    引数:    dstp    - コピー先アドレス
  1291. *        srcp    - コピー元アドレス
  1292. *    返値:    dstp 上のコピー終了時の'\0'のアドレス
  1293. */
  1294. static
  1295. char *___stpcpy(char *dstp, const char *srcp)
  1296. {
  1297.     while (*dstp++ = *srcp++) {
  1298.     }
  1299.     return (dstp - 1);    /* 1文字行き過ぎてるので */
  1300. }
  1301.  
  1302. /* 自家製 strlast()
  1303. *    引数:    strp    - 被処理文字列アドレス
  1304. *    返値:    strp の最後の'\0'の位置
  1305. */
  1306. static
  1307. char *___strlast(const char *strp)
  1308. {
  1309.     while (*strp++) {
  1310.     }
  1311.     return (char *)(strp - 1);    /* 1文字行き過ぎてるので */
  1312. }
  1313.  
  1314. /*
  1315. *    ↓↓↓ hufilec のみのライブラリ共通関数 ↓↓↓
  1316. *        inline 展開されることを期待する
  1317. */
  1318. /* 一番最後にあるパス区切り文字を探す
  1319. *    引数:    fnamp    - 被検索ファイル名へのポインタ
  1320. *    返値:    最後のパス区切り文字のアドレス
  1321. *        見つからなかったら NULL
  1322. */
  1323. static
  1324. char *___find_last_sepa(const char *fnamp)
  1325. {
  1326.     const char *cp = fnamp;
  1327.  
  1328.     while (1) {
  1329.         cp = strrpbrk(cp, "/:\\");
  1330.  
  1331.         if ((cp == NULL)        /* 見つからなかった */
  1332.          || (cp == fnamp)        /* ファイル名の最初 */
  1333.          || !iskanji(*(cp - 1))        /* 漢字2バイト目でない */
  1334.         ) {
  1335.             /* 区切り文字発見or見つからなかった */
  1336.             break;        /* これ以上回ってもしょうがないのでループ中断 */
  1337.         }
  1338.     }
  1339.     return (char *)cp;
  1340. }
  1341.  
  1342.  
  1343. -_fgtnamp.c
  1344. /* フルパスファイル名文字列中のファイル名部分の開始アドレスを取得する
  1345. *    引数:    fnamp    - ファイル名へのポインタ
  1346. *    返値:    fnamp 中のファイル名の開始アドレス
  1347. *    注記    * fnamp がファイル名だけだった場合は、fnamp をそのまま返す。
  1348. */
  1349. char *fgetnamep(const char *fnamp)
  1350. {
  1351.     char *result;
  1352.  
  1353.     /* パス名の最後の位置を取得 */
  1354.     result = ___find_last_sepa(fnamp);
  1355.     if (result != NULL) {    /* 見つかってたら */
  1356.         result++;        /* その次からがファイル名 */
  1357.     } else {        /* 見つからなければ */
  1358.         result = (char *)fnamp;    /* 文字列全てがファイル名 */
  1359.     }
  1360.     return result;
  1361. }
  1362.  
  1363. -_fcutpath.c
  1364. /* ファイル名からパス名(ドライブ名およびディレクトリ名)部分のみを切り出す
  1365. *    引数:    pbufp    - 切り出したパス名の格納バッファアドレス
  1366. *        fnamp    - 処理対象ファイル名へのポインタ
  1367. *    返値:    pbufp の値
  1368. *    注記    * fnamp にパス名が存在しない場合、pbufp には空文字列が
  1369. *        格納される。
  1370. *        * この関数は構成要素を字面から分解するだけであり、分解した
  1371. *        文字列が正しいかはチェックしない。
  1372. *        * 漢字もそれなりに考慮しているが、完璧とは言えない。
  1373. */
  1374. char *fcutpath(char *pbufp, const char *fnamp)
  1375. {
  1376.     const char *endp;
  1377.  
  1378.     /* パス名の最後の位置を保持しておく */
  1379.     endp = ___find_last_sepa(fnamp);
  1380.  
  1381.     /* パス名の切り出し */
  1382.     while (fnamp <= endp) {    /* パス名がない(endp == NULL)場合はここで引っ掛かるので転送されない */
  1383.         *pbufp++ = *fnamp++;
  1384.     }
  1385.     *pbufp = '\0';
  1386.  
  1387.     return pbufp;
  1388. }
  1389.  
  1390. -_sepfnam.c
  1391. /* ファイル名を各構成要素に分解する
  1392. *    引数:    drvp    - ドライブ名("O:" など)格納バッファアドレス
  1393. *        dirp    - ディレクトリ名("Here\comes\" など)格納バッファアドレス
  1394. *        basep    - ファイル名("The_Newest" など)格納バッファアドレス
  1395. *        extp    - 拡張子(".Day" など)格納バッファアドレス
  1396. *        fnamp    - 分解されるファイル名へのポインタ
  1397. *    注記    * 該当する要素が fnamp に存在しない場合、バッファには
  1398. *        空文字列が格納される。
  1399. *        * 渡されたバッファアドレスが NULL だったら、その構成要素は
  1400. *        バッファに書き込まない。
  1401. *        * この関数は構成要素を字面から分解するだけであり、分解した
  1402. *        文字列が正しいかはチェックしない。
  1403. *        * 漢字もそれなりに考慮しているが、完璧とは言えない。
  1404. */
  1405. void separate_file_name(char *drvp, char *dirp, char *basep, char *extp, const char *fnamp)
  1406. {
  1407.     char drvexist = (fnamp[1] == ':');
  1408.     const char *stap, *endp;
  1409.  
  1410.     /* パス名の最後の位置を保持しておく */
  1411.     endp = ___find_last_sepa(fnamp);
  1412.  
  1413.     /* ドライブ名 */
  1414.     if (drvp != NULL) {
  1415.         if (drvexist) {    /* ドライブ名があれば分解 */
  1416.             *drvp++ = fnamp[0];
  1417.             *drvp++ = fnamp[1];
  1418.         }
  1419.         *drvp = '\0';
  1420.     }
  1421.     /* ディレクトリ名 */
  1422.     if (dirp != NULL) {
  1423.         stap = (drvexist)? &fnamp[2]: fnamp;
  1424.         while (stap <= endp) {    /* パス名がない(endp == NULL)場合はここで引っ掛かるので転送されない */
  1425.             *dirp++ = *stap++;
  1426.         }
  1427.         *dirp = '\0';
  1428.     }
  1429.     /* ファイル名 */
  1430.     if (basep != NULL) {
  1431.         stap = (endp == NULL)? fnamp: endp + 1;
  1432.         strcpy_brk(basep, stap, ".");    /* 拡張子があればそこまで、なければ最後まで */
  1433.     }
  1434.     /* 拡張子 */
  1435.     if (extp != NULL) {
  1436.         stap = getextpos0(fnamp);    /* stap=拡張子開始位置 */
  1437.         while (*extp++ = *stap++) {    /* 終わりまでコピー */
  1438.         }
  1439.     }
  1440. }
  1441.  
  1442. -_rmkfnam.c
  1443. #define        ATR    0x3f
  1444.  
  1445. /* ファイル名の拡張子をすげ替えて、存在しないファイル名を作成する
  1446. *    引数:    fnbufp    - ファイル名の基準文字列
  1447. *            & 作成ファイル名の格納バッファアドレス
  1448. *    返値:    作成できれば fnbufp、できなければ NULL
  1449. *    注記    * 拡張子変更前のファイル名が存在するかはチェックしない。
  1450. *        * fnbufp には、3文字の拡張子が格納できるだけの容量が必要
  1451. *        である。
  1452. *        * ファイル名の変更は、拡張子を"000"~"999"に書き換えること
  1453. *        で行なう。そのどれもが存在していたら「作成できない」ことに
  1454. *        なる。
  1455. *        * 作成できなければ、fnbufp は同じ文字列になる。
  1456. */
  1457. char *remake_unsame_filename(char *fnbufp)
  1458. {
  1459.     short i;
  1460.     char *xp;        /* 拡張子開始位置 */
  1461.     char xkeep[8];        /* 拡張子保存域 */
  1462.  
  1463. #if    0
  1464.     /* 変更前のがあるのか調べてみる */
  1465.     if (!fexist(fnbufp, ATR)) {    /* なければ */
  1466.         return fnbufp;    /* そのままでいい */
  1467.     }
  1468. #endif
  1469.     /* 元の拡張子を保存 */
  1470.     xp = getextpos0(fnbufp);    /* xp=拡張子の位置 */
  1471.     ___vstrcpy(xkeep, xp);        /* 今の拡張子を保存しておく */
  1472.  
  1473.     /* 拡張子変更・存在判定ループ
  1474.     *    ※このキミョーなループ処理は、dbra を使わせるための処置。
  1475.     */
  1476.     i = 1000 - 1;
  1477.     do {
  1478.         sprintf(xp, ".%.3d", (1000 - 1) - i);    /* 拡張子書き込み */
  1479.         if (!fexist(fnbufp, ATR)) {    /* そのファイルがなければ */
  1480.             return fnbufp;        /* それを持って返る */
  1481.         }
  1482.     } while (--i != -1);
  1483.  
  1484.     /* 全て存在していた */
  1485.     ___vstrcpy(xp, xkeep);    /* 保存していた拡張子を書き戻す */
  1486.     return NULL;
  1487. }
  1488.  
  1489. -_fcatpat.c
  1490. /* ファイル名冒頭にパス名を付加する
  1491. *    パスが指定されていたら付加しない
  1492. *
  1493. *    引数:    fnamp    - ファイル名文字列へのポインタ
  1494. *            兼 処理結果格納バッファアドレス
  1495. *        pathp    - パス名文字列へのポインタ
  1496. *    返値:    fnamp の値
  1497. *    注記    * pathp が空文字列だった場合、パス名の付加は行なわれ
  1498. *        ない。
  1499. *        * pathp の最後に '\'(バックスラッシュ)または '/'(スラッシュ) が
  1500. *        なかったら、「環境変数 SLASH が定義されていれば '/'、
  1501. *        未定義ならば '\'」を付加する。
  1502. *        * fnamp にはパス名を付加できるだけの余裕が必要である。
  1503. */
  1504. char *fcatpath(char *fnamp, const char *pathp)
  1505. {
  1506.     char *cp, *kp;
  1507.  
  1508.     if (!is_null_str(pathp)) {    /* pathp が空でなければ */
  1509.         if (!is_there_path(fnamp)) {        /* パス名が指定されてない */
  1510.             kp = strdup(fnamp);        /* まずファイル名を保存 */
  1511.             cp = ___stpcpy(fnamp, pathp);    /* パス名をバッファ冒頭にコピー */
  1512.             if (!is_path_sepa_mac(*(cp - 1))) {    /* 最後に区切りがなければ */
  1513.                 *cp++ = path_separator();    /* 付加しておいてから */
  1514.             }
  1515.             ___vstrcpy(cp, kp);        /* その後ろに保存しといたファイル名を転送 */
  1516.         }
  1517.     }
  1518.     return fnamp;        /* 引数のアドレスをそのまま返す */
  1519. }
  1520.  
  1521. -_fgsssp.c
  1522. /* テキストファイルから1行読み込む
  1523. *    読み込んだ行の先頭に空白文字があればそれを読み飛ばす
  1524. *
  1525. *    引数:    bufp    - 格納バッファアドレス
  1526. *        size    - 読み込むサイズ
  1527. *        fp    - 読み込みファイルポインタ
  1528. *    返値:    エラー又は EOF の場合は NULL、
  1529. *        でなければ読み込み行の行頭にある空白文字を
  1530. *        スキップしたアドレス
  1531. */
  1532. char *fgets_skipsp(char *bufp, size_t size, FILE *fp)
  1533. {
  1534.     char *result;
  1535.  
  1536.     result = fgets(bufp, size, fp);
  1537.     if (result != NULL) {
  1538.         while (isspace(*result)) {
  1539.             result++;
  1540.         }
  1541.     }
  1542.     return result;
  1543. }
  1544.  
  1545. -_fgetsb.c
  1546. /* fgets バイナリ版
  1547. *    バイナリオープンされたファイルから fgets() した
  1548. *    文字列の最後から2文字目が '\r' だった場合にそれを削除、
  1549. *    以降の文字を1つ前にずらす
  1550. *
  1551. *    引数:    bufp    - 読み込み内容格納バッファアドレス
  1552. *        size    - 最大読み込みサイズ
  1553. *        fp    - 読み込みファイルのファイルポインタ
  1554. *    返値:    成功すれば bufp、失敗したか EOF だったら NULL
  1555. *    注記    * 最後から2文字目以外の '\r' 文字には手を付けない。
  1556. */
  1557. char *fgetsb(char *bufp, size_t size, FILE *fp)
  1558. {
  1559.     bufp = fgets(bufp, size, fp);
  1560.     if (bufp != NULL) {    /* 読み込めてたら */
  1561.         /* 行末チェック */
  1562.         char *cp = ___strlast(bufp) - 2;    /* cp='\r' がありそうな場所 */
  1563.  
  1564.         if ((cp >= bufp) && (*cp == '\r')) {    /* 実際に '\r' があれば */
  1565.             *cp = *(cp + 1);    /* その後ろの1文字で '\r' を上書き */
  1566.             *(cp + 1) = '\0';    /* 文字列を終わらせる */
  1567.         }
  1568.     }
  1569.     return bufp;
  1570. }
  1571.  
  1572. -_fgetsnn.c
  1573. /* ファイルから一行読み込む
  1574. *    行末にある改行 '\n' または復帰改行 '\r\n' は取り除かれる
  1575. *
  1576. *    引数:    bufp    - 読み込み行の格納バッファアドレス
  1577. *        size    - 格納バッファのサイズ
  1578. *        fp    - 読み込みファイルポインタ
  1579. *    返値:    成功すれば bufp、失敗したか EOF だったら NULL
  1580. */
  1581. char *fgetsnn(char *bufp, size_t size, FILE *fp)
  1582. {
  1583.     bufp = fgets(bufp, size, fp);
  1584.     if (bufp != NULL) {    /* 読み込めてたら */
  1585.         /* 行末チェック */
  1586.         char *cp = ___strlast(bufp) - 1;    /* cp='\r\n' がありそうな場所 */
  1587.  
  1588.         if (*cp == '\n') {    /* 改行文字発見 */
  1589.             if (*(cp - 1) == '\r') {    /* その前に復帰文字もある */
  1590.                 --cp;
  1591.             }
  1592.             *cp = '\0';    /* 文字列を完結させる */
  1593.         }
  1594.     }
  1595.  
  1596.     return bufp;
  1597. }
  1598.  
  1599. -_setstim.c
  1600. #include    <utime.h>
  1601. #include    <sys\stat.h>
  1602.  
  1603.  
  1604. /* ファイル日時をもう一つのファイルに合わせる
  1605. *    引数:    dstfnp    - 日時変更するファイル名
  1606. *        srcfnp    - 変更日時元のファイル名
  1607. *    返値:    設定できれば 0、エラーがあったら !0
  1608. */
  1609. int set_same_file_time(const char *dstfnp, const char *srcfnp)
  1610. {
  1611.     int result = !0;
  1612.     struct stat stbuf;
  1613.  
  1614.     if (stat(srcfnp, &stbuf) == 0) {
  1615.         if (utime(dstfnp, (struct utimbuf *)&(stbuf.st_atime)) == 0) {
  1616.             result = 0;
  1617.         }
  1618.     }
  1619.     return result;
  1620. }
  1621.  
  1622. -_setftim.c
  1623. #include    <time.h>
  1624. #include    <utime.h>
  1625.  
  1626.  
  1627. /* ファイル日時を設定する
  1628. *    引数:    fnamp    - 日時変更するファイル名
  1629. *        tim    - 設定日時
  1630. *            (世界標準時(UTC)での1970年1月1日午前0時0分0秒からの通算秒数)
  1631. *    返値:    設定できれば 0、エラーがあったら !0
  1632. */
  1633. int set_file_time(const char *fnamp, time_t tim)
  1634. {
  1635.     struct utimbuf utbuf;
  1636.  
  1637.     utbuf.modtime = tim;
  1638.     return utime(fnamp, &utbuf);
  1639. }
  1640.  
  1641. -_getftim.c
  1642. #include    <time.h>
  1643. #include    <sys\stat.h>
  1644.  
  1645.  
  1646. /* ファイル日時を取得する
  1647. *    引数:    fnamp    - 日時変更するファイル名
  1648. *    返値:    指定ファイルの最終更新日時
  1649. *        (世界標準時(UTC)での1970年1月1日午前0時0分0秒からの通算秒数)
  1650. *        エラーがあったら -1
  1651. */
  1652. time_t get_file_time(const char *fnamp)
  1653. {
  1654.     time_t result = 0;
  1655.     struct stat sts;
  1656.  
  1657.     if (!stat(fnamp, &sts)) {
  1658.         result = sts.st_mtime;
  1659.     }
  1660.     return result;
  1661. }
  1662.  
  1663.